package com.yuju.pay.service.impl;



import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.ExtendParams;
import com.alipay.demo.trade.model.builder.AlipayTradePayRequestBuilder;
import com.alipay.demo.trade.model.builder.AlipayTradeRefundRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPayResult;
import com.alipay.demo.trade.model.result.AlipayF2FRefundResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import com.yuju.cache.RedisCache;
import com.yuju.common.Result;
import com.yuju.constant.CacheKey;
import com.yuju.constant.Constant;
import com.yuju.enums.AlipayReturnCodeEnum;
import com.yuju.enums.ReturnStatusEnum;
import com.yuju.group.enums.EmployeeReturnCodeEnum;
import com.yuju.pay.service.IAlipayService;


@Service
public class AlipayServiceImpl implements IAlipayService{

    // 支付宝当面付2.0服务
	@Autowired
    private static AlipayTradeService service;
	private static RedisCache<String, String> redisCache = RedisCache.getInstance();



    // 当面付2.0支付
    /**
     * 
     * 功能: <br/>
     * 
     * 重写：zhousc <br/>
     * 
     * @Date ：2018年2月6日 上午10:06:26<br/>
     * 
     * @param outTradeNo:订单号 <br/>
     * 		  hotelName:门店名字 <br/>
     * 		  totalAmount:金额<br/>
     * 		  authCode:付款条码<br/>
     * 		  body:订单描述<br/>
     * 		  appAuthToken：授权令牌<br/>
     *		  operatorId:操作员编号<br/>
     *		  storeId:分店ID<br/>
     *		  providerId:业务扩展参数
     * @see com.yuju.pay.service.IAlipayService#trade_pay(java.lang.String)
     */
    @Override
    public Result pay(String outTradeNo ,String hotelName ,String totalAmount ,String authCode ,
    						String body ,String appAuthToken ,String operatorId ,String storeId ,
    						String providerId) {
    	this.init();
    	Result returnResult = new Result();
        // (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店消费”
        String subject = "寓居品牌"+hotelName+"门店当面付消费";

        // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId(providerId);

        // 支付超时，线下扫码交易定义为5分钟
        String timeoutExpress = "5m";

        // 创建条码支付请求builder，设置请求参数
        AlipayTradePayRequestBuilder builder = new AlipayTradePayRequestBuilder()
                        .setAppAuthToken(appAuthToken)
            .setOutTradeNo(outTradeNo).setSubject(subject).setAuthCode(authCode)
            .setTotalAmount(totalAmount).setStoreId(storeId)
            .setBody(body).setOperatorId(operatorId)
            .setExtendParams(extendParams)
            .setTimeoutExpress(timeoutExpress);

        // 调用tradePay方法获取当面付应答
        AlipayF2FPayResult result = service.tradePay(builder);
        System.out.println("状态：" + result.getTradeStatus());
    	System.out.println("状态码：" + result.getResponse().getCode());
    	System.out.println("订单号：" + result.getResponse().getTradeNo());
    	System.out.println("商户订单号：" + result.getResponse().getOutTradeNo());
    	System.out.println("描述：" + result.getResponse().getMsg());
    	System.out.println("子代码：" + result.getResponse().getSubCode());
    	System.out.println("子描述：" + result.getResponse().getSubMsg());
    	
        switch (result.getTradeStatus()) {
            case SUCCESS:
                System.out.println("支付宝支付成功: )");
                returnResult.setStatus(ReturnStatusEnum.SUCCESS.getCode());
            	returnResult.setMsg(ReturnStatusEnum.SUCCESS.getDesc());
            	returnResult.setData(result.getResponse().getTradeNo());
            	returnResult.setReturnCode("子代码：" + result.getResponse().getSubCode());
            	returnResult.setReturnMsg("子描述：" + result.getResponse().getSubMsg());
            	
                return returnResult;
                
            case FAILED:
                System.err.println("支付宝支付失败!!!");
                returnResult.setStatus(ReturnStatusEnum.FAILURE.getCode());
            	returnResult.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            	returnResult.setReturnCode("子代码：" + result.getResponse().getSubCode());
            	returnResult.setReturnMsg("子描述：" + result.getResponse().getSubMsg());
            	
                return returnResult;
            case UNKNOWN:
                System.err.println("系统异常，订单状态未知!!!");
                returnResult.setStatus(ReturnStatusEnum.FAILURE.getCode());
            	returnResult.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            	returnResult.setReturnCode("子代码：" + result.getResponse().getSubCode());
            	returnResult.setReturnMsg("子描述：" + result.getResponse().getSubMsg());;
            	
                return returnResult;

            default:
                System.out.println("不支持的交易状态，交易返回异常!!!");
                returnResult.setStatus(ReturnStatusEnum.FAILURE.getCode());
            	returnResult.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            	returnResult.setReturnCode("子代码：" + result.getResponse().getSubCode());
            	returnResult.setReturnMsg("子描述：" + result.getResponse().getSubMsg());
            	
                return returnResult;
        }
        
        
        
    }
    /**
     * 
     * 功能：当面付2.0退款<br/>
     *@param outTradeNo:订单号 <br/>
     *		 refundAmount:金额 <br/>
     *		 refundReason：退款原因<br/>
     *		 storeId：门店编号
     * @author zhousc
     * @Date 2018年2月6日 下午5:09:55 <br/>
     */
    @Override
    public Result refund(String outTradeNo ,String refundAmount ,
    						String refundReason ,String storeId ,String appAuthToken) {
    	this.init();
    	Result returnResult = new Result();
        // 创建退款请求builder，设置请求参数
        AlipayTradeRefundRequestBuilder builder = new AlipayTradeRefundRequestBuilder()
            .setOutTradeNo(outTradeNo).setRefundAmount(refundAmount).setRefundReason(refundReason)
//            .setOutRequestNo(outRequestNo)
            .setStoreId(storeId).setAppAuthToken(appAuthToken);

        AlipayF2FRefundResult result = service.tradeRefund(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
            	System.out.println("支付宝退款成功: )");
            	returnResult.setStatus(ReturnStatusEnum.SUCCESS.getCode());
            	returnResult.setMsg(ReturnStatusEnum.SUCCESS.getDesc());
            	returnResult.setData(result.getResponse().getTradeNo());
            	returnResult.setReturnCode("子代码：" + result.getResponse().getSubCode());
            	returnResult.setReturnMsg("子描述：" + result.getResponse().getSubMsg());
            	
            	return returnResult;
            case FAILED:
            	System.err.println("支付宝退款失败!!!");
            	returnResult.setStatus(ReturnStatusEnum.FAILURE.getCode());
            	returnResult.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            	returnResult.setReturnCode("子代码：" + result.getResponse().getSubCode());
            	returnResult.setReturnMsg("子描述：" + result.getResponse().getSubMsg());
            	
                return returnResult;
            case UNKNOWN:
            	System.err.println("系统异常，订单退款状态未知!!!");
            	returnResult.setStatus(ReturnStatusEnum.FAILURE.getCode());
            	returnResult.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            	returnResult.setReturnCode("子代码：" + result.getResponse().getSubCode());
            	returnResult.setReturnMsg("子描述：" + result.getResponse().getSubMsg());
            	
                return returnResult;
            default:
            	System.err.println("不支持的交易状态，交易返回异常!!!");
            	returnResult.setStatus(ReturnStatusEnum.FAILURE.getCode());
            	returnResult.setMsg(ReturnStatusEnum.FAILURE.getDesc());
            	returnResult.setReturnCode("子代码：" + result.getResponse().getSubCode());
            	returnResult.setReturnMsg("子描述：" + result.getResponse().getSubMsg());
            	
            	return returnResult;
        }
    }
	
    private void init(){
	    /** 一定要在创建AlipayTradeService之前调用Configs.init()设置默认参数
	     *  Configs会读取classpath下的zfbinfo.properties文件配置信息，如果找不到该文件则确认该文件是否在classpath目录
	     */
	//    Configs.init("zfbinfo.properties");
      	Configs.setOpenApiDomain(redisCache.get(Constant.OPEN_API_DOMAIN + CacheKey.KEY_SYS_PARAM));
      	Configs.setMcloudApiDomain(redisCache.get(Constant.MCLOUD_API_DOMAIN + CacheKey.KEY_SYS_PARAM));

      	Configs.setPid(redisCache.get(Constant.PARTNER_ID + CacheKey.KEY_SYS_PARAM));
      	Configs.setAppid(redisCache.get(Constant.ALIPAY_APPID + CacheKey.KEY_SYS_PARAM));

          // RSA
      	Configs.setPrivateKey(redisCache.get(Constant.UNIVERSAL_PRIVATE_KEY + CacheKey.KEY_SYS_PARAM)); 
      	Configs.setPublicKey(redisCache.get(Constant.UNIVERSAL_PUBLIC_KEY + CacheKey.KEY_SYS_PARAM));  
      	Configs.setAlipayPublicKey(redisCache.get(Constant.ALIPAY_PUBLIC_KEY + CacheKey.KEY_SYS_PARAM));  
      	Configs.setSignType(redisCache.get(Constant.SIGN_TYPE + CacheKey.KEY_SYS_PARAM));

          // 查询参数
      	Configs.setMaxQueryRetry(Integer.parseInt(redisCache.get(Constant.MAX_QUERY_RETRY + CacheKey.KEY_SYS_PARAM)));  
      	Configs.setQueryDuration(Long.parseLong(redisCache.get(Constant.QUERY_DURATION + CacheKey.KEY_SYS_PARAM)));  
      	Configs.setMaxCancelRetry(Integer.parseInt(redisCache.get(Constant.MAX_CANCEL_RETRY + CacheKey.KEY_SYS_PARAM))); 
      	Configs.setCancelDuration(Long.parseLong(redisCache.get(Constant.CANCEL_DURATION + CacheKey.KEY_SYS_PARAM))); 

          // 交易保障调度线程
      	Configs.setHeartbeatDelay(Long.parseLong(redisCache.get(Constant.HEARTBEAT_DELAY + CacheKey.KEY_SYS_PARAM))); 
      	Configs.setHeartbeatDuration(Long.parseLong(redisCache.get(Constant.HEARTBEAT_DURATION + CacheKey.KEY_SYS_PARAM)));
      	
          /** 使用Configs提供的默认参数
           *  AlipayTradeService可以使用单例或者为静态成员对象，不需要反复new
           */
          service = new AlipayTradeServiceImpl.ClientBuilder().build();
      }
    
}
